home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 551-575 / disk_566 / bomber / sources / sound.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  4KB  |  217 lines

  1. /*
  2.  *     sound.c
  3.  *
  4.  */
  5.  
  6. #include "Bomber.h"
  7. #include <exec/memory.h>
  8. #include <dos/dos.h>
  9. #include <devices/audio.h>
  10. #include "sound.h"
  11.  
  12.  
  13. #if DEBUG
  14. # define D(debug) debug
  15. #else
  16. # define D(debug)
  17. #endif
  18.  
  19.  
  20. /*------------------------- Externe Daten...*/
  21.  
  22.  
  23. extern struct ExecBase    *SysBase;
  24. extern struct Library    *DOSBase;
  25.  
  26. extern long                audio;
  27.  
  28.  
  29. /*------------------------- Daten dieses Moduls...*/
  30.  
  31.  
  32. struct Voice8Header
  33. {
  34.     ULONG oneShotHiSamples,
  35.           repeatHiSamples,
  36.           samplesPerHiCycle;
  37.     UWORD sampleRate;
  38.     UBYTE ctOctave,
  39.           sCompression;
  40.     LONG  volume;
  41. };
  42.  
  43.  
  44. struct ChunkHeader
  45. {
  46.     ULONG name,
  47.           length;
  48. };
  49.  
  50.  
  51. struct MsgPort            *audioport = NULL;
  52. struct IOAudio            *ioaudio = NULL,
  53.                         ioa_samples[ SOUND_ANZAHL ],
  54.                         ioa_allocate;
  55.  
  56. int                        pending_sound_plays = 0;
  57.  
  58. UBYTE                    *sample_daten[ SOUND_ANZAHL ];
  59.  
  60. struct Unit                *units[2];
  61. int                        last_unit = 0;
  62.  
  63.  
  64. /*------------------------- Code-Definitionen...*/
  65.  
  66.  
  67. void load_sound( char *name, int number )
  68. {
  69.     struct Voice8Header        v8h;
  70.     struct ChunkHeader        chunk;
  71.     BPTR                    file;
  72.     UBYTE                    **mem = & sample_daten[ number ];
  73.     struct IOAudio            *ioa  = & ioa_samples[ number ];
  74.     
  75.     #define VHDR 0x56484452L
  76.     #define BODY 0x424f4459L
  77.     #define CLOCK 3546895
  78.     
  79.     
  80.     file = Open( name, MODE_OLDFILE );
  81.     if( !file ) return;
  82.     
  83.     chunk.length = 12;
  84.     do
  85.     {
  86.         Seek( file, chunk.length, OFFSET_CURRENT );
  87.         Read( file, &chunk, 8 );
  88.     } while( chunk.name != VHDR );
  89.     
  90.     Read( file, &v8h, sizeof(v8h) );
  91.     
  92.     chunk.length -= sizeof(v8h);
  93.     do
  94.     {
  95.         Seek( file, chunk.length, OFFSET_CURRENT );
  96.         Read( file, &chunk, 8 );
  97.     } while( chunk.name != BODY );
  98.     
  99.     *mem = AllocMem( chunk.length, MEMF_CHIP );
  100.     
  101.     if( *mem )
  102.     {
  103.         Read( file, *mem, chunk.length );
  104.         
  105.         *ioa = ioa_allocate;
  106.         
  107.         ioa->ioa_Request.io_Message.mn_ReplyPort = audioport;
  108.         ioa->ioa_Request.io_Command              = CMD_WRITE;
  109.         ioa->ioa_Request.io_Flags                = ADIOF_PERVOL;
  110.         
  111.         ioa->ioa_Length  = chunk.length;
  112.         ioa->ioa_Period  = CLOCK / v8h.sampleRate;
  113.         ioa->ioa_Volume  = v8h.volume / 1024;
  114.         ioa->ioa_Cycles  = 1;
  115.     }
  116.     
  117.     ioa->ioa_Data = *mem;
  118.     
  119.     Close( file );
  120. }
  121.  
  122.  
  123. void free_sound( int number )
  124. {
  125.     UBYTE                    *mem = sample_daten[ number ];
  126.     struct IOAudio            *ioa = & ioa_samples[ number ];
  127.     
  128.     if( mem ) FreeMem( mem, ioa->ioa_Length );
  129. }
  130.  
  131.  
  132. void init_sound( void )
  133. {
  134.     static UBYTE which_channels[] = { 3, 5, 10, 12 };
  135.     
  136.     audioport = CreateMsgPort();
  137.     audio = 1L << audioport->mp_SigBit;
  138.     
  139.     memset( &ioa_samples,  0, sizeof ioa_samples  );
  140.     memset( &ioa_allocate, 0, sizeof ioa_allocate );
  141.     
  142.     ioa_allocate.ioa_Request.io_Message.mn_ReplyPort = audioport;
  143.     
  144.     ioa_allocate.ioa_Request.io_Command = ADCMD_ALLOCATE;
  145.     ioa_allocate.ioa_Request.io_Flags   = ADIOF_NOWAIT;
  146.     ioa_allocate.ioa_Data               = which_channels;
  147.     ioa_allocate.ioa_Length             = sizeof(which_channels);
  148.     
  149.     if( OpenDevice( AUDIONAME, 0, &ioa_allocate.ioa_Request, 0 ) == 0 )
  150.     {
  151.         load_sound( "click.snd",     SOUND_CLICK );
  152.         load_sound( "explosion.snd", SOUND_EXPLOSION );
  153.         load_sound( "sieg.snd",      SOUND_SIEG );
  154.         load_sound( "anfang.snd",    SOUND_ANFANG );
  155.         load_sound( "highscore.snd", SOUND_HIGHSCORE );
  156.         
  157.         // Kanäle ausfiltern
  158.         units[0] = units[1] = ioa_allocate.ioa_Request.io_Unit;
  159.         units[0] = (struct Unit *)((long)units[0] & 6);        // rechter Kanal
  160.         units[1] = (struct Unit *)((long)units[1] & 9);        // linker Kanal
  161.     }
  162.     D( else PutStr( "Audio Open Failure\n" ); )
  163. }
  164.  
  165.  
  166. void handle_audioreply( void )
  167. {
  168.     struct IOAudio *m;
  169.     
  170.     while( m = GetMsg(audioport) )
  171.     {
  172.         FreeMem( m, sizeof(*m) );
  173.         --pending_sound_plays;
  174.     }
  175. }
  176.  
  177.  
  178. void close_sound( void )
  179. {
  180.     while( pending_sound_plays )
  181.     {
  182.         WaitPort( audioport );
  183.         handle_audioreply();
  184.     }
  185.     
  186.     if( ioa_allocate.ioa_Request.io_Device )
  187.     {
  188.         CloseDevice( &ioa_allocate.ioa_Request );
  189.     }
  190.     
  191.     if( audioport ) DeleteMsgPort( audioport );
  192.     
  193.     free_sound( SOUND_CLICK );
  194.     free_sound( SOUND_EXPLOSION );
  195.     free_sound( SOUND_SIEG );
  196.     free_sound( SOUND_ANFANG );
  197.     free_sound( SOUND_HIGHSCORE );
  198. }
  199.  
  200.  
  201. void sound_play( int number )
  202. {
  203.     if( ioaudio = AllocMem( sizeof(*ioaudio), NULL ) )
  204.     {
  205.         *ioaudio = ioa_samples[ number ];
  206.         
  207.         if( ioaudio->ioa_Data )
  208.         {
  209.             last_unit = 1 - last_unit;
  210.             ioaudio->ioa_Request.io_Unit = units[last_unit];
  211.             
  212.             BeginIO( & ioaudio->ioa_Request );
  213.             ++pending_sound_plays;
  214.         }
  215.     }
  216. }
  217.